﻿/*-----------------------------------------------
// File: BCAttackMoveForwardState.cs
// Description: 
// Author: Shaobing	492057342@qq.com
-----------------------------------------------*/
using UnityEngine;
using System.Collections;

namespace Battle.View
{
    public class BCAttackMoveForwardState : Fsm.FsmStateMonoBase<ActorState>
    {
        BattleCharacter bc
        {
            get { return this.controller as BattleCharacter; }
        }
        public BCAttackMoveForwardState(ActorState state, BattleCharacter ctrl) : base(state, ctrl) { }

        OnceBehaviourPackage currentPackage {
            get { return bc.GetCurrentPackage(); }
        }

        Vector3 targetPos;
        float moveSpeed;
        Vector3 moveDir;

        public Vector3 GetTargetPos() { return targetPos; }
        float moveTime
        {
            get {
                if (bc.heroClass == (int)HeroClass.Hero || bc.heroClass == (int)HeroClass.Main_Actor_Man || bc.heroClass == (int)HeroClass.Main_Actor_Woman)
                {
                    return Dict.Blo.DictConfigBlo.GetAttackMoveForwardTime();
                }
                else if (bc.heroClass == (int)HeroClass.Monster)
                {
                    return Dict.Blo.DictConfigBlo.GetMonsterAttackMoveForwardTime();
                }
                else {
                    return Dict.Blo.DictConfigBlo.GetAttackMoveForwardTime();
                }

            }
        }


        float deltaTime = 0f;
        public override void Enter()
        {
            deltaTime = 0f;
            targetPos = SelectSkillReleasePosition();
            targetPos = CheckReleasePositionOverLay(targetPos);
            moveDir = (targetPos - bc.transform.localPosition).normalized;
            if (bc.heroClass == (int)HeroClass.Hero || bc.heroClass == (int)HeroClass.Main_Actor_Man || bc.heroClass == (int)HeroClass.Main_Actor_Woman)
            {
                moveSpeed = Vector3.Distance(targetPos, bc.transform.localPosition) / (float)(bc.rushFallTime - bc.rushFlyTime);
                bc.PlayRush();
            }
            else if (bc.heroClass == (int)HeroClass.Monster) {
                moveSpeed = Vector3.Distance(targetPos, bc.transform.localPosition) / moveTime;
                bc.PlayRun();
            }
        }

        void Move() {
            var dis = Vector3.Distance(targetPos, bc.transform.localPosition);
            if (dis <= Time.deltaTime * moveSpeed)
            {
                bc.transform.localPosition = targetPos;
            }
            else
            {
                var newPos = bc.transform.localPosition + moveDir * moveSpeed * Time.deltaTime;
                bc.transform.LookAt(newPos);
                bc.transform.localPosition = newPos;
            }
        }
        public override void Update()
        {
            deltaTime += Time.deltaTime;
            if (bc.heroClass == (int)HeroClass.Hero || bc.heroClass == (int)HeroClass.Main_Actor_Man || bc.heroClass == (int)HeroClass.Main_Actor_Woman)
            {
                if (deltaTime >= bc.rushFlyTime && deltaTime < bc.rushFallTime)
                {
                    Move();
                }
            }
            else {
                Move();
            }

            if (deltaTime >= moveTime) {
                bc.SwitchState(ActorState.Attack);
                return;
            }
        }

        public override void Leave()
        {
            bc.transform.localPosition = targetPos;
            bc.transform.localEulerAngles = bc.GetStandEulerAngle();
        }

        public Vector3 GetTargetPosition() {
            return targetPos;
        }

        public float overlapDis {
            get {
                return Dict.Blo.DictConfigBlo.GetAttackOverlapDistance(); 
            }
        }
        Vector3 CheckReleasePositionOverLay(Vector3 pos)
        {
            int forward = Random.Range(0, 2);
            Vector3 curPos = pos;
            while (IsOverLay(curPos))
            {
                if (forward == 0)
                {
                    curPos += new Vector3(overlapDis + 0.1f, 0, 0);
                }
                else {
                    curPos += new Vector3(-overlapDis - 0.1f, 0, 0);
                }
            }
            return curPos;

        }
        bool IsOverLay(Vector3 pos)
        {
            foreach (var uid in BattleViewCtrl.GetInstance().GetActorUids(bc.camp))
            {
                var _bc = BattleViewCtrl.GetInstance().GetBattleCharacter(uid);
                if (bc.uniqueId == _bc.uniqueId)
                    continue;
                var dis = Vector3.Distance(pos, _bc.GetAttackReleaseAccodingToPosition());
                if (dis < overlapDis)
                {
                    return true;
                }
            }
            return false;
        }

        Vector3 SelectSkillReleasePosition()
        {
            int currentFPId = currentPackage.FPId;
            BattleCamp currentFPCamp = currentPackage.FPIdCamp;
            var currentSkill = bc.GetSkill(currentPackage.skillType);
            switch (currentSkill.selectRule)
            {
                case SkillCastSelectPointRule.MeleeForward:
				{
					var targetBC = BattleViewCtrl.GetInstance().GetBattleCharacter(currentFPCamp, currentFPId);
					Vector3 deltaDis = Vector3.zero;
					if (targetBC != null) {
						deltaDis = new Vector3 (0, 0, (float)currentSkill.selectRuleArgs + targetBC.length / 2);
					}
                    if (bc.camp == BattleCamp.Attacker)
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + deltaDis * (-1f);
                    else
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + deltaDis * 1f;
                }
				case SkillCastSelectPointRule.MeleeCenter:
                    if (bc.camp == BattleCamp.Attacker)
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + new Vector3(0, 0, -(float)currentSkill.selectRuleArgs);
                    else
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + new Vector3(0, 0, (float)currentSkill.selectRuleArgs);
                case SkillCastSelectPointRule.MelleBackward:
				{
					var targetBC = BattleViewCtrl.GetInstance().GetBattleCharacter(currentFPCamp, currentFPId);
					Vector3 deltaDis = Vector3.zero;
					if (targetBC != null){
						deltaDis = new Vector3 (0, 0, (float)currentSkill.selectRule - bc.length / 2f);
					}
                    if (bc.camp == BattleCamp.Attacker)
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + deltaDis * (-1f);
                    else
                        return BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp) + deltaDis * 1f;
				}
                case SkillCastSelectPointRule.Remote:
                    return BattleViewCtrl.GetInstance().GetPosition(bc.FPId, bc.camp);
                case SkillCastSelectPointRule.Row:
                    var pos = BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp);
                    if (bc.camp == BattleCamp.Attacker)
                    {
                        return new Vector3(0, 0, pos.z) + new Vector3(0, 0, -(float)currentSkill.selectRuleArgs);
                    }
                    else {
                        return new Vector3(0, 0, pos.z) + new Vector3(0, 0, (float)currentSkill.selectRuleArgs);
                    }
                case SkillCastSelectPointRule.Col:
                    var pos0 = BattleViewCtrl.GetInstance().GetPosition(currentFPId, currentFPCamp);
                    if (bc.camp == BattleCamp.Attacker) {
                        return new Vector3(pos0.x, 0, BattleViewCtrl.GetInstance().GetForwardPositionZ(bc.camp)) + new Vector3(0, 0, -(float)currentSkill.selectRuleArgs);
                    }
                    else {
                        return new Vector3(pos0.x, 0, BattleViewCtrl.GetInstance().GetForwardPositionZ(bc.camp)) + new Vector3(0, 0, (float)currentSkill.selectRuleArgs);
                    }
                default:
                    return Vector3.zero;
            }

        }
    }
}
